package com.angysnail.guava.monitor;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockTest<V> {
	private final ReentrantLock lock = new ReentrantLock();
	private final Condition valuePresent = lock.newCondition();
	private final Condition valueAbsent = lock.newCondition();
	private V value;

	public static void main(String[] args) throws InterruptedException {
		ReentrantLockTest<String> test = new ReentrantLockTest<String>();
		Thread thread = new Thread("thread" + 0) {
			@Override
			public void run() {
				super.run();
				try {
					test.get();
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		};
		thread.start();
		Thread thread1 = new Thread("thread" + 1) {
			@Override
			public void run() {
				super.run();
				try {
					test.set("value" + 1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		thread1.start();
	}

	public V get() throws InterruptedException {
		lock.lock();
		try {
			// 还是要用while不能用if
			while (value == null) {
				// --在此处进行等待
				valuePresent.await();
			}
			V result = value;
			value = null;
			// 避免了使用notifyAll()
			valueAbsent.signal();
			return result;
		} finally {
			lock.unlock();
		}
	}

	public void set(V newValue) throws InterruptedException {
		lock.lock();
		try {
			while (value != null) {
				valueAbsent.await();
			}
			value = newValue;
			valuePresent.signal();
		} finally {
			// 执行这步后，上面的get即可走下去了
			lock.unlock();
		}
	}
}
